其他
教你打造一个万能的适配器
androidstarjack的博客地址:
http://blog.csdn.net/androidstarjack/article/details/56841473
最近项目中 经常用listView和GridView ,可以说是项目中Listview GridView几乎是必用的组件,Android也提供一套机制,为这些控件绑定数据,那就是Adapter 最近抽了时间,自己也打造了一个万能的适配器
看我们之前的一些写法:
public class BillAdapter extends BaseAdapter{
List<BillVo> newsList;
Activity activity;
LayoutInflater inflater = null; public BillAdapter(Activity activity, List<BillVo> newsList) { this.activity = activity; this.newsList = newsList;
inflater = LayoutInflater.from(activity);
} @Override
public int getCount() { return newsList == null ? 0 : newsList.size();
} @Override
public Object getItem(int position) { if (newsList != null && newsList.size() != 0) { return newsList.get(position);
} return null;
} @Override
public long getItemId(int position) { return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
BillVo item = newsList.get(position);
ViewHolder holder = ViewHolder.get(parent, convertView, R.layout.item_bill, position); if(item.getScore().contains("-")){
holder.setText(R.id.jia_bill_money, item.getScore());
holder.getView(R.id.jian_bill_money).setVisibility(View.INVISIBLE);
holder.getView(R.id.jia_bill_money).setVisibility(View.VISIBLE);
}else{
holder.setText(R.id.jian_bill_money, "+" + item.getScore());
holder.getView(R.id.jian_bill_money).setVisibility(View.VISIBLE);
holder.getView(R.id.jia_bill_money).setVisibility(View.INVISIBLE);
}
holder.setText(R.id.bill_name, item.getSource());
holder.setText(R.id.bill_time, Util.timeStampDate(item.getCreatetime(), "yyyy-MM-dd")); return holder.getConvertView();
}
}
这样用起来虽然还不错,但每次都需要去继承一个BaseAdapter,然后实现里面的一大堆方法,而我们每次最关心的无非就是getView方法,其余的方法几乎都是相同代码。这里是不是就可以优化起来呢?在其次,我们在使用Adapter的时候,为了优化性能,常常会创建一个Holder。而Holder里面每次存放的都是View,对Holer的操作无非也就是初始化,绑定数据,复用。这里是不是也可以抽取抽取? 如果我们封装后:
/**
* 类功能描述:</br>
*v Viewholder
* @author yuyahao
* @version 1.0 </p> 修改时间:</br> 修改备注:</br>
*/public class VolTeamAdapter extends CommonAdapter<Bean> {
private Context context;
public VolTeamAdapter(Context context, List<Bean> listDatas, int layoutId) { super(context, listDatas, layoutId);
} @Override
protected void fillData(ViewHolder holder, int position) { TextView actNum = holder.getView(R.id.team_item_active_num); TextView time = holder.getView(R.id.team_item_time); TextView title = holder.getView(R.id.team_item_title); ImageView icon = holder.getView(R.id.team_item_icon); Bean item = listDatas.get(position);
actNum.setText(String.valueOf(item.getActiveSum()) + "个");
time.setText(String.valueOf(item.getTimeSun()) + "h");
title.setText(item.getName()); GlideUtil.loadNetImgC(context,icon, item.getPhoto(), R.drawable.bg_app_title);
}
}
这样是不是简单多了。每次 写adapter都可以这样用。
第一步:构造 BaseAdapter
**
* 类功能描述:</br>
*v 使用
* @author yuyahao
* @version 1.0 </p> 修改时间:</br> 修改备注:</br>
*/
public class VolTeamAdapter extends CommonAdapter<Bean> {
private Context context;
public VolTeamAdapter(Context context, List<Bean> listDatas, int layoutId) { super(context, listDatas, layoutId); this.context = context;
} @Override
protected void fillData(ViewHolder holder, int position) { TextView actNum = holder.getView(R.id.team_item_active_num); TextView time = holder.getView(R.id.team_item_time); TextView title = holder.getView(R.id.team_item_title); ImageView icon = holder.getView(R.id.team_item_icon); Bean item = listDatas.get(position);
actNum.setText(String.valueOf(item.getActiveSum()) + "个");
time.setText(String.valueOf(item.getTimeSun()) + "h");
title.setText(item.getName()); GlideUtil.loadNetImgC(context,icon, item.getPhoto(), R.drawable.bg_app_title);
}
}
好了,别卖关子了,直接上全部代码。
/**
* 类功能描述:</br>
*v Viewholder
* @author yuyahao
* @version 1.0 </p> 修改时间:</br> 修改备注:</br>
*/public abstract class CommonAdapter<T> extends BaseAdapter { /*** 上下文的Context*/
protected Context mContext; /*** list的数据*/
protected List<T> listDatas; /** Item布局ID*/
protected int layoutId; public CommonAdapter(Context context, List<T> listDatas, int layoutId) { this.mContext = context; this.listDatas = listDatas; this.layoutId = layoutId;
} @Override
public int getCount() { return listDatas == null ? 0 : listDatas.size();
}/**
* 获取当前点击的Item的数据时用
* 在onItemClick中 parent.getAdapter().getItem(),获取当前点击的Item的数据
*/
@Override
public Object getItem(int position) { return listDatas.get(position);
} @Override
public long getItemId(int position) { return position;
} /**
*加载每一个Item,该方法是最关键的
*/@ Override public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = ViewHolder.getViewHolder(mContext, convertView, parent, layoutId, position);
fillData(holder, position); return holder.getMConvertView();
} /**
*
* 抽象方法,用于子类实现,填充数据
* @param holder
* @param position
*/
protected abstract void fillData(ViewHolder holder, int position);
}
第二步Holer的通用化
/**
* 类功能描述:</br>
*v Viewholder * @author yuyahao
* @version 1.0 </p> 修改时间:</br> 修改备注:</br>
*/
public class ViewHolder {
private int mPosition;
/**
* View容器,用于存放Holer中的View * 据网上说是 SparseArray是这样的 * SparseArray 是Android推荐使用的一个优化容器,相当于一个Map<integer,View>
*/
private SparseArray<View> mViews;
/**
* Item布局View convertView */
private View mConvertView;
public ViewHolder(Context context, ViewGroup parent, int layoutId) {
mViews = new SparseArray<View>();
mConvertView = LayoutInflater.from(context).inflate(layoutId, null);
mConvertView.setTag(this);
}
/**
* 获取ViewHolder * @param context
* 上下文 * @param convertView
* @param parent
* @param layoutId
* 布局layout Id * @param
* @return
*/
public static ViewHolder getViewHolder(Context context, View convertView, ViewGroup parent, int layoutId) {
if (convertView == null)
return new ViewHolder(context, parent, layoutId);
return (ViewHolder) convertView.getTag();
}
public ViewHolder(Context context, ViewGroup parent, int layoutId, int position) {
this.mViews = new SparseArray<View>();
this.mPosition = position;
this.mConvertView = LayoutInflater.from(context).inflate(layoutId,
parent, false);
this.mConvertView.setTag(this);
}
/**
* 拿到一个ViewHolder对象 * @param context
* @param convertView
* @param parent
* @param layoutId
* @param position
* @return
*/
public static ViewHolder getViewHolder(Context context, View convertView, ViewGroup parent, int layoutId, int position) {
if (null == convertView) {
return new ViewHolder(context, parent, layoutId, position);
} else {
ViewHolder holder = (ViewHolder) convertView.getTag();
holder.mPosition = position;
return holder;
}
}
/**
* 获取Holder中的ItemView * @param viewId
* @return
*/ @SuppressWarnings("unchecked")
public <T extends View> T getView(int viewId) {
View item = mViews.get(viewId);
if (item == null) {
item = mConvertView.findViewById(viewId);
mViews.put(viewId, item);
}
return (T) item;
}
/** * 获取convertView***/
public View getMConvertView() {
return mConvertView;
}
}
这样已经写完。
第三步使用
/**
* 类功能描述:</br>
*v 使用
* @author yuyahao
* @version 1.0 </p> 修改时间:</br> 修改备注:</br>
*/public class VolTeamAdapter extends CommonAdapter<Bean> {
private Context context;
public VolTeamAdapter(Context context, List<Bean> listDatas, int layoutId) { super(context, listDatas, layoutId); this.context = context;
} @Override
protected void fillData(ViewHolder holder, int position) { TextView actNum = holder.getView(R.id.team_item_active_num); TextView time = holder.getView(R.id.team_item_time); TextView title = holder.getView(R.id.team_item_title); ImageView icon = holder.getView(R.id.team_item_icon); Bean item = listDatas.get(position);
actNum.setText(String.valueOf(item.getActiveSum()) + "");
time.setText(String.valueOf(item.getTimeSun()) + "");
title.setText(item.getName()); GlideUtil.loadNetImgC(context,icon, item.getPhoto(), R.drawable.bg_app_title);
}
}
mainActivity:
public class MyTextActivity extends BaseActivity{
private Context cnt; @Bind(R.id.lv_list) ListView lv_list; @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState);
addViewFillInRoot(R.layout.ctivity_mytext); ButterKnife.bind(this);
cnt = this;
initView();
} private void initView() { try { List<Bean> list = DataTest.getMyTestList(); VolTeamAdapter volTeamAdapter = new VolTeamAdapter(cnt,list,R.layout.my_listr);
lv_list.setAdapter(volTeamAdapter);
} catch (Exception e) {
e.printStackTrace();
}
}
}
xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:gravity="center_vertical"
android:layout_height="match_parent">
<ImageView
android:layout_width="@dimen/dp80"
android:layout_height="@dimen/dp80"
android:background="@drawable/default_head"
android:scaleType="fitXY"
android:id="@+id/team_item_icon"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_marginLeft="@dimen/dp10"
android:orientation="vertical"
android:layout_height="@dimen/dp80">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/team_item_title"
android:gravity="center_vertical"
android:layout_weight="1"
android:text="卡卡罗特"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="天不排名"
android:id="@+id/team_item_time"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp20"
android:text="战斗值: "
android:id="@+id/team_item_active_num"/>
</LinearLayout>
</LinearLayout></LinearLayout>
效果图:
相信自己,没有做不到的,只有想不到的
如果你觉得此文对您有所帮助,欢迎入群 QQ交流群 :232203809 微信公众号:终端研发部
(欢迎关注学习和交流)